/*
Copyright (c) 2008 Raul Sanchez

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
 */

/**
 * RSAccordion turns any UL tag and its LI tags into an accordion widget. 
 * To implement RSAccordion the method must be called derectly in the UL tag.
 * The LI tags are expected to have two visible HTML elements (P, A, DIV, etc).
 * 
 * An example of the required UL tag is
 * <ul>
 * 	<li>
 * 		<div calss="openAction rs_accordion_bar">
 * 			<span class="titleAction">Bar #1</span>
 * 		</div>
 * 		<div class="rs_accordion_content">
 * 			Some content for the bar number 1
 * 		</div>
 * 	</li>
 * 	<li>
 * 		<div calss="openAction rs_accordion_bar">
 * 			<span class="titleAction">Bar #2</span>
 * 		</div>
 * 		<div class="rs_accordion_content">
 * 			Some content for the bar number 2
 * 		</div>
 * 	</li>
 * </ul>
 * 
 * A much simple example could be
 * <ul>
 * 	<li>
 * 		<p calss="openAction rs_accordion_bar titleAction">Bar #1</p>
 * 		<p class="rs_accordion_content">Some content for the bar number 1</p>
 * 	</li>
 * 	<li>
 * 		<p calss="openAction rs_accordion_bar titleAction">Bar #2</p>
 * 		<p class="rs_accordion_content">Some content for the bar number 2</p>
 * 	</li>
 * </ul>
 * 
 * @param properties
 */
$.fn.RSAccordion = function(properties){
  	var wrapper = $(this);
		wrapper.version = "0.1";
		wrapper.allowDebugging = null;
		wrapper.itemCount = 0;
		wrapper.items = new Array();
  		/* Accordion Events */
  		wrapper.events = new Object();
		wrapper.events.onBuild = "onBuild";
		wrapper.events.onDestroy = "onDestroy";
		wrapper.events.onReady = "onReady";
		wrapper.events.onNewItem = "onNewItem";
		wrapper.events.onItemDeleted = "onItemDeleted";
		
		/* Setting up properties */
  		wrapper.properties = properties != null? properties : new Object(); 
		wrapper.properties.wrapperClassName  = properties.wrapperClassName != null? properties.wrapperClassName  : "rs_accordion_wrapper";
		wrapper.properties.barClassName 	 = properties.barClassName != null? 	properties.barClassName 	 : "rs_accordion_bar";
		wrapper.properties.contentClassName = properties.contentClassName!= null? properties.contentClassName : "rs_accordion_content";
		wrapper.properties.titleActionClassName = properties.titleActionClassName!= null? properties.titleActionClassName : "titleAction";
		wrapper.properties.openActionClassName = properties.openActionClassName!= null? properties.openActionClassName : "openAction";
		wrapper.properties.callback = properties.callback!= null? properties.callback : function(acc){};
		wrapper.properties.speed = properties.speed != null? properties.speed : 250;
		
		/**
		 * Item Handler
		 */
  		var RSAccordionItemHanlder = function(liElement){
  			var _that = this;
  			var _visible = false;
  			var _speed = "fast";
  			var _speedValues = {slow:"slow", normal:"normal", fast:"fast"};
  			var _item = $(liElement);
  			var _content = $(liElement).find("*."+ wrapper.properties.contentClassName);
  			var _handler = $(liElement).find("*."+ wrapper.properties.openActionClassName);
  			var _bar = $(liElement).find("*." + wrapper.properties.barClassName);
  			
  			
  			/* +=====================+ */
  			/* |   Private methods   | */
  			/* +=====================+ */
  			var _statusChanged = function(){
  				$(this).trigger("update", this);
  			};
  			
  			var _validateSpeedValue = function(s){
  				var flag = _speedValues.hasOwnProperty(s.toLowerCase());
  				return flag
  			};
  			
  			
  			/* +====================+ */
  			/* |   Public methods   | */
  			/* +====================+ */
  			
  			this.setSpeed = function(s){
  				if(_validateSpeedValue(s)){
  					_speed = s;
  				}
  			};
  			
  			
  			this.isOpen = function(){
  				return _visible;
  			};
  			
  			this.open = function(){
  				_content.slideDown(_speed, _statusChanged);
  				_visible = true;
  			};
  			
  			
  			this.close = function(){
  				_content.slideUp(_speed, _statusChanged);
  				_visible = false;
  			};
  			
  			this.toggle = function(){
  				if(_visible){
  					this.close();
  				}else{
  					this.open();
  				}
  			};
  			
  			this.getHTMLElement = function(){
  				return _item;
  			};
  			
  			/* +==================+ */
  			/* |   Initianlize    | */
  			/* +==================+ */
  			
  			$(_handler).click(function(){
  				_that.toggle();
  			});
  			
  			$(_content).hide();
  			return this;
  		};
  		
		
		
		
  		/**
  		 * @param index Accordion item index number
  		 * @return Accordion item
  		 */
  		wrapper.getItemByIndex = function(index){
  			var item = null;
  			for(var i=0; i<this.items.length; i++){
  				if(i == index){
					item = this.items[i];
					break;
  				}
  			}
  			return item;
  		};
  		
  		
  		/**
  		 * @param title Accordion item title name
  		 * @return Accordion item
  		 */
  		wrapper.getItemByTitle = function(title){
  			var item = null;
  			for(var i=0; i<this.items.length; i++){
  				var htmlElem = this.items[i].getHTMLElement();
  				var thisTitle =  $(htmlElem).find("*."+ wrapper.properties.titleActionClassName);
  				if(thisTitle.length > 0 && thisTitle.html() == title){
					item = this.items[i];
					break;
  				}
  			}
  			return item;
  		};
  		
  		
  		
  		
  		wrapper.addItemAt = function(liElement, index){
  			if(liElement == null) return;
  			if(index == null) index = (this.count() + 1);
  			var item = wrapper._initItem(liElement);
  			var elem = item.getHTMLElement();
  			if(index <= 0){ 
  				var first = $(this).find("li:first");
  					elem.insertBefore(first);
  					this.items.unshift(item);
  			}else if(index >= this.count()){
  				var first = $(this).find("li:last");
  					elem.insertAfter(first);
  					this.items.push(item);
  			}else if(this.count() == 0){
  				$(this).append(elem);
  			}else{
  				var liElements = $(this).find("li");
  				for(var i=0; i<liElements.length; i++){
  					if(i == index){
  						elem.insertBefore($(liElements[i]));
  						this.items.splice(index, 0, item);
  						break;
  					}
  				}
  			}
  			wrapper.itemCount += 1;
  			return elem;
  		};
  		
  		
  		/**
  		 * 
  		 */
  		wrapper.addItem = function(liElement){
  			return this.addItemAt(liElement, this.count());
  		};
  		
  		
  		wrapper._initItem = function(liElement){
  			var item = new RSAccordionItemHanlder(liElement);
  			return item;
  		};
  		
  		wrapper._isValidEvent = function(eventName){
  			var flag = this.events.hasOwnProperty(eventName);
  			return flag;
  		};
  		
  		wrapper._dispatchAccordionEvent = function(eventName){
  			if(this._isValidEvent(eventName)){
  				wrapper.trigger(eventName, wrapper);
  			}
  		};
  		
  		/**
  		 * Removes all the 'li' elements from the accordion
  		 */
  		wrapper._destroy = function(){
  			wrapper.find("li").remove();
  			wrapper._dispatchAccordionEvent(wrapper.events.onDestroy);
  		};
  		

  		wrapper.draw = function(ulList){
  			var accordion = this;
  			var onBuild = function(){
  				accordion.slideDown(200);
  				wrapper._dispatchAccordionEvent(wrapper.events.onReady);
  			}
  			
  			var onHide = function(){
	  			accordion._destroy();
	  			ulElem = $(ulList);
		  		var itemList = ulElem.find("li");
			  		itemList.each(function(){
				  		var bar = $(this).find("div:first");
			  			var content = $(this).find("div:last");
	  					accordion.addItem(bar, content);
			  		});
			  	onBuild();
  			};
  			
  			this.slideUp(200, onHide);
  		};
  		
  		
  		
  		wrapper.parse = function(ulList){
  			ulElem = $(ulList);
  			ulElem.addClass(this.properties.wrapperClassName);
	  		var itemList = ulElem.find("li");
		  		itemList.each(function(){
		  			wrapper.items.push(wrapper._initItem(this));
		  		});
		  	return wrapper;
  		};
  		
  		
  		wrapper.count = function(){
  			return this.items.length;
  		}
  		
  		wrapper.log = function(msg){
  			if(this.allowDebugging == true){
	  			try{
	  				window.console.log(msg);
	  			}catch(e){}
  			}else if(this.allowDebugging == null){
  				var location = document.location.toString();
  				this.allowDebugging = (location.indexOf("debug=true") > -1? true : false);
  				this.log(msg);
  			}
  		};
  		
  		wrapper.parse(this);
	  	// TODO
	  	
	  	wrapper.setProperty = function(name, value){};
	  	wrapper.addActionByClassName = function(className, action){};
	  	wrapper.removeItemAt = function(index){};
	  	wrapper.transform = function(customFunction){};
	  	wrapper._onBarStateChangeEvent = function(){}; // fire when tab is openned or closed
	  	wrapper._onItemChangeEvent = function(){}; // 
	  	
	  	
	  	
	  	
	  	
	  	//
  		wrapper.bind(wrapper.events.onReady, (function(){return wrapper;})(), wrapper.properties.callback);
  		wrapper._dispatchAccordionEvent(wrapper.events.onReady);
  		
  		
	return wrapper;
};
  
// TODO:

$.fn.RSAccordionTab = function(accordion){};
$.fn.RSAccordionContent = function(accordion){};
$.fn.RSAccordionItem = function(accordion){};


  
  